
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>自动化你的代码提交流程 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>自动化你的代码提交流程 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">自动化代码提交流程主要能带来哪三个核心好处？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">1. 提高效率：自动化可以节省开发者手动执行测试、格式化代码和编写提交信息等步骤的时间，使其能专注于核心开发任务。2. 减少错误：自动化流程能强制执行最佳实践，减少因手动操作（如忘记运行测试或提交不规范的代码）导致的人为错误。3. 确保代码质量：可以在提交代码前自动运行静态分析、单元测试和代码格式化工具，从而保证入库代码的质量。</div>
          </div>
          <div class="card-source">来源: 1. 为什么需要自动化代码提交流程？</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">什么是 Git 钩子（Git Hooks），它在自动化流程中扮演什么角色？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Git 钩子是 Git 提供的一种脚本机制，它允许在特定的 Git 事件（例如提交或推送）发生时自动执行预设的脚本。通过这种机制，可以在开发者的本地环境中实现代码提交流程的自动化。</div>
          </div>
          <div class="card-source">来源: 2. 使用 Git 钩子自动化本地提交流程</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">请描述 `pre-commit`、`commit-msg` 和 `pre-push` 这三个常见 Git 钩子的功能。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">`pre-commit`：在执行代码提交（commit）操作前触发，常用于运行单元测试和代码格式化。`commit-msg`：在提交信息写入前执行，用于验证提交信息的格式是否规范。`pre-push`：在推送（push）代码到远程仓库前执行，常用于运行集成测试或更全面的代码规范检查。</div>
          </div>
          <div class="card-source">来源: 2.1 常见的 Git 钩子</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">与 CI/CD 工具相比，单独使用 Git 钩子进行自动化存在什么主要局限性？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Git 钩子的主要局限性在于它们只能在本地运行，因此无法强制覆盖团队中的所有成员。要实现团队范围内的、统一的代码提交流程自动化，需要借助 CI/CD 工具（如 Jenkins、GitHub Actions）在远程仓库层面进行配置。</div>
          </div>
          <div class="card-source">来源: 3. 使用 CI/CD 工具自动化远程提交流程</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">如何通过 GitHub Actions 实现当代码被推送到特定分支时自动运行单元测试和静态分析？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">需要在项目的 `.github/workflows` 目录下创建一个 YAML 配置文件（如 `ci.yml`）。在该文件中，使用 `on` 关键字指定触发工作流的事件（如 `push` 到 `main` 分支），然后在 `jobs` 中定义具体的步骤，包括检出代码（actions/checkout）、设置运行环境（如 JDK），以及执行单元测试（`mvn test`）和静态分析（`mvn spotless:check`）的命令。</div>
          </div>
          <div class="card-source">来源: 3.1 使用 GitHub Actions 自动化代码检查</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">模式</div>
          <div class="card-question">根据文档中的 Jenkins Pipeline 示例，一个完整的自动化构建、测试和部署流程通常包含哪几个阶段（stages）？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">模式</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">根据文档中的 Jenkins Pipeline 示例，一个完整的流程通常包含三个核心阶段：1. Build（构建）：执行 `mvn clean package` 来打包应用。2. Test（测试）：执行 `mvn test` 来运行单元测试。3. Deploy（部署）：执行 `mvn deploy` 将应用部署到目标环境。</div>
          </div>
          <div class="card-source">来源: 3.2 使用 Jenkins 自动化代码部署</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">除了 Git 钩子和 CI/CD 工具外，文档还介绍了哪种方法来进一步自动化代码提交流程？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">文档还介绍了通过编写自定义脚本（例如 Bash 脚本）来进一步自动化代码提交流程。这种脚本可以将多个步骤串联起来，例如自动生成提交信息、运行测试、添加更改、提交代码并最终推送到远程仓库。</div>
          </div>
          <div class="card-source">来源: 4. 使用自定义脚本进一步自动化</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">文档中的 `commit-msg` 钩子脚本是如何确保提交信息格式合规的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">该脚本通过读取提交信息文件的内容，然后使用 `grep` 命令和一个正则表达式 `^(feat|fix|docs|style|refactor|test|chore): .{10,}` 来进行匹配。如果提交信息不符合这个预定义的格式，脚本会输出错误提示并以非零状态码退出，从而中断提交过程。</div>
          </div>
          <div class="card-source">来源: 2.3 实现自动化 commit-msg 钩子</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">在 GitHub Actions 的工作流配置中，`on` 关键字及其子配置（如 `push` 和 `pull_request`）的作用是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">`on` 关键字用于定义触发整个工作流的事件。其子配置可以更精确地控制触发条件，例如 `on: push: branches: [ main ]` 表示只有当代码被推送到 `main` 分支时，该工作流才会被触发。</div>
          </div>
          <div class="card-source">来源: 3.1 使用 GitHub Actions 自动化代码检查</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
